<?php
declare(strict_types = 1);

namespace app\controller;

use hg\apidoc\annotation as Apidoc;

use app\service\ZhdHttpService;
use support\Request;
use support\Response;

/**
 * @Apidoc\Title("对外 REST接口")
 * @Apidoc\Group("http")
 */
class HttpController
{
    public function __construct(private ZhdHttpService $svc = new ZhdHttpService())
    {
    }

    private function respond(string $path, callable $fn): Response
    {
        try {
            $ret = $fn();
            // 服务层错误统一约定：['ok'=>false,'error'=>...]
            if (is_array($ret) && isset($ret['ok']) && $ret['ok'] === false) {
                return json(['ok' => false, 'error' => $ret['error'] ?? 'unknown error', 'path' => $path]);
            }
            return json(['ok' => true, 'data' => $ret]);
        } catch (\Throwable $e) {
            return json(['ok' => false, 'error' => $e->getMessage(), 'path' => $path]);
        }
    }

    /**
     * @Apidoc\Title("登录")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunDengLu")
     * @Apidoc\Desc("用户登录接口，验证用户名密码并返回登录结果")
     * @Apidoc\Param(name="z2", type="string", require=true, desc="登录名,默认：13523033229")
     * @Apidoc\Param(name="z3", type="string", require=true, desc="密码，默认：123456")
     * @Apidoc\Param(name="z4", type="int", require=false, default="0", desc="版本号 默认0")
     * @Apidoc\Param(name="z5", type="string", require=false, default="", desc="唯一号 默认空字符串")
     * @Apidoc\Param(name="z6", type="string", require=false, default="", desc="默认空字符串")
     * @Apidoc\Param(name="z7", type="string", require=false, default="", desc="默认空字符串")
     * @Apidoc\Param(name="z8", type="string", require=false, default="", desc="默认空字符串")
     * @Apidoc\Param(name="z9", type="int", require=false, default="4", desc="平台登录类型 默认4")
     * @Apidoc\Param(name="z10", type="string", require=false, default="", desc="默认空字符串")
     * @Apidoc\Returned(name="ok", type="bool", desc="请求是否成功")
     * @Apidoc\Returned(name="data", type="object",desc="数据结果集", children={ 
     *      @Apidoc\Returned(name="z1", type="string", desc="指令标识"),
     *      @Apidoc\Returned(name="z2", type="int", desc="登录结果：0=成功, 1=失败, 2=异常"),
     *      @Apidoc\Returned(name="z3", type="string", desc="唯一号（登录成功后返回）"),
     *      @Apidoc\Returned(name="z4", type="int", desc="登录状态：0=登录过, 1=未登录过"),
     *      @Apidoc\Returned(name="z5", type="int", desc="短信功能：0=否, 1=是"),
     *      @Apidoc\Returned(name="error", type="string", desc="错误信息，成功时为null"),
     *      @Apidoc\Returned(name="path", type="string", desc="接口名称")
     * })
     * @Apidoc\ResponseStatus({
     *     {"code": 200, "desc": "请求成功"},
     *     {"code": 400, "desc": "参数错误"},
     *     {"code": 401, "desc": "登录失败"}
     * })
     */
    public function FunDengLu(Request $request): Response
    {
        error_log('FunDengLu called with params: ' . json_encode($request->post()));
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunDengLu($request->post()));
    }

    /**
     * @Apidoc\Title("保持连接")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunBaoChi")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号(登录返回的 z3)")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true)
     * @Apidoc\Returned(name="error", type="string", desc="错误信息")
     * @Apidoc\Returned(name="path", type="string", desc="接口名")
     */
    public function FunBaoChi(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunBaoChi($request->post()));
    }

    /**
     * @Apidoc\Title("获取组和车辆信息")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunDwGetZu")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_strTj", type="string", require=false, desc="查询条件")
     * @Apidoc\Param(name="p_iFs", type="int", require=false, default="0", desc="查询方式：0全部；1车牌；2设备号")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="array", desc="数据结果集", main=true, children={
     * @Apidoc\Returned(children={
     *      @Apidoc\Returned(name="ZuId", type="string", desc="组ID"),
     *      @Apidoc\Returned(name="Name", type="string", desc="组名称"),
     *      @Apidoc\Returned(name="CheNum", type="int", desc="设备数量")
     * }),
     * })
     */
    public function FunDwGetZu(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunDwGetZu($request->post()));
    }

    /**
     * @Apidoc\Title("获取车辆信息")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunDwGetChe")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_ZuId", type="string", require=true, desc="组ID")
     * @Apidoc\Param(name="p_Idx", type="int", require=false, default="0", desc="起始索引")
     * @Apidoc\Param(name="p_Co", type="int", require=false, default="50", desc="每次获取数量")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="array", main=true, desc="数据结果集",children={
     * @Apidoc\Returned(children={
     *      @Apidoc\Returned(name="ID", type="string", desc="设备ID"),
     *      @Apidoc\Returned(name="CP", type="string", desc="车牌"),
     *      @Apidoc\Returned(name="DJ", type="int", desc="运动状态：0静止/1运动/2未知"),
     *      @Apidoc\Returned(name="DWZX", type="int", desc="定位状态：0未知/1卫星/2基站/3未定位/4离线/5WiFi"),
     *      @Apidoc\Returned(name="sSbLx", type="string", desc="设备类型")
     * }),
     * })
     */
    public function FunDwGetChe(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunDwGetChe($request->post()));
    }

    /**
     * @Apidoc\Title("获取车辆详细信息")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunDwGetCheXinXi")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_CheId", type="string", require=true, desc="设备ID(车ID)")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true, desc="数据结果集", children={
     *      @Apidoc\Returned(name="ID", type="string", desc="设备ID（车辆ID"),
     *      @Apidoc\Returned(name="CheZaiShouJiHao", type="string", desc="车载手机号：即设备标配的SIM卡号码"),
     *      @Apidoc\Returned(name="CheZaiWeiYiHao",type="string",desc="车载唯一号：即终端设备唯一号，作为设备的唯一标识"),
     *      @Apidoc\Returned(name="ChePaiHaoMa",type="string",desc="车牌号码"),
     *      @Apidoc\Returned(name="CheZhuXingMing",type="string",desc="车主姓名"),
     *      @Apidoc\Returned(name="CheZhuDianHua1",type="string",desc="车主电话1"),
     *      @Apidoc\Returned(name="CheZhuDianHua2",type="string",desc="车主电话2"),
     * })
     */
    public function FunDwGetCheXinXi(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunDwGetCheXinXi($request->post()));
    }

    /**
     * @Apidoc\Title("获取车辆状态（列表刷新）")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunGetCheState")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true, desc="数据结果集", children={
     *      @Apidoc\Returned(name="m_iNum", type="int", desc="设备数量"),
     *      @Apidoc\Returned(name="m_State", type="array", desc="列表 [{ID,DJ,DWZX}]", children={
     *          @Apidoc\Returned(name="ID", type="string", desc="设备ID"),
     *          @Apidoc\Returned(name="DJ", type="int", desc="运动状态：0静止/1运动/2未知"),
     *          @Apidoc\Returned(name="DWZX", type="int", desc="定位状态：0未知/1卫星/2基站/3未定位/4离线/5WiFi定位")
     * })
     * })
     */
    public function FunGetCheState(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunGetCheState($request->post()));
    }

    /**
     * @Apidoc\Title("下发车辆状态参数（返回处理条数）")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunGetCheStateEx")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_CheIdList", type="array", require=true, desc="设备ID集合，如 ['1_114079','1_147224']")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="int", main=true, desc="处理的条数")
     */
    public function FunGetCheStateEx(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunGetCheStateEx($request->post()));
    }

    /**
     * @Apidoc\Title("获取指定设备实时跟踪定位信息")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunDwGetOne")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_CheId", type="string", require=true, desc="设备ID(车ID)")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true, desc="数据结果集", children={
     *      @Apidoc\Returned(name="TZ", type="string", desc="该参数无需处理"),
     *      @Apidoc\Returned(name="iTz", type="int", desc="该参数无需处理"),
     *      @Apidoc\Returned(name="iGQ", type="int", desc="设备是否已过期；1过期（限制访问）、0未过期"),
     *      @Apidoc\Returned(name="BZ", type="string", desc="设备备注信息"),
     *      @Apidoc\Returned(name="XMState", type="float", desc="休眠状态true休眠、false未休眠"),
     *      @Apidoc\Returned(name="m_iYyxsc", type="int", desc="该参数无需处理"),
     *      @Apidoc\Returned(name="m_iJlxmsc", type="int", desc="该参数无需处理"),
     *      @Apidoc\Returned(name="m_iBcxmsc", type="int", desc="该参数无需处理"),
     *      @Apidoc\Returned(name="m_iZcbs", type="int", desc="该参数无需处理"),
     *      @Apidoc\Returned(name="sSbLx", type="string", desc="设备类型:有线/无线"),
     *      @Apidoc\Returned(name="sJzZbB", type="string", desc="多基站百度坐标信息(百度坐标)格式。A,经度，纬度|B,经度，纬度|…其中字母代表基站编号、经纬度为零则无需显示"),
     *      @Apidoc\Returned(name="sJzZbG", type="string", desc="多基站GPS坐标信息(百度坐标)格式A,经度，纬度|B,经度，纬度|…其中字母代表基站编号、经纬度为零则无需显示"),
     *      @Apidoc\Returned(name="bJd", type="string", desc="百度坐标经度"),
     *      @Apidoc\Returned(name="bWd", type="string", desc="百度坐标纬度"),
     *      @Apidoc\Returned(name="SY", type="string", desc="该参数无需处理"),
     *      @Apidoc\Returned(name="CT", type="string", desc="该参数无需处理"),
     *      @Apidoc\Returned(name="ID", type="string", desc="设备ID"),
     *      @Apidoc\Returned(name="CP", type="string", desc="车牌号码"),
     *      @Apidoc\Returned(name="SIM", type="string", desc="车载手机号（GPS终端安装的SIM卡号码）"),
     *      @Apidoc\Returned(name="JD", type="string", desc="GPS坐标经度"),
     * })
     */
    public function FunDwGetOne(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunDwGetOne($request->post()));
    }

    /**
     * @Apidoc\Title("定时获取定位信息")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunDwGetDwTimer")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_DwTime", type="string", require=true, default="2000/01/01 00:00:00", desc="最后获取定位时间")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true, desc="数据结果集",children={
     *      @Apidoc\Returned(name="m_Nums", type="int", desc="定位信息条数"),
     *      @Apidoc\Returned(name="m_Dw", type="array", desc="定位信息列表"),
     *      @Apidoc\Returned(name="strTime", type="string", desc="定位信息列表"),
     * })
     */
    public function FunDwGetDwTimer(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunDwGetDwTimer($request->post()));
    }

    /**
     * @Apidoc\Title("定时获取定位信息（带选中车辆列表）")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunDwGetDwTimerEx")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_CheIdList", type="array", require=true, desc="已选设备ID列表，如 ['1_114079','1_147224']")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true, desc="数据结果集",children={
     *      @Apidoc\Returned(name="m_Nums", type="int", desc="定位信息条数"),
     *      @Apidoc\Returned(name="m_Dw", type="array", desc="定位信息列表"),
     *      @Apidoc\Returned(name="strTime", type="string", desc="定位信息列表"),
     * })
     */
    public function FunDwGetDwTimerEx(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunDwGetDwTimerEx($request->post()));
    }

    /**
     * @Apidoc\Title("获取指定设备实时跟踪定位信息（前端定时10秒）")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunDwGetOneListAPI")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_CheId", type="string", require=true, desc="设备ID(车ID)")
     * @Apidoc\Param(name="p_LastTime", type="string", require=true, desc="yyyy-MM-dd HH:mm:ss；首次为当前北京时间；之后传最后一条XT时间")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true, desc="数据结果集",children={
     *      @Apidoc\Returned(name="TZ", type="string", desc="该参数无需处理"),
     *      @Apidoc\Returned(name="iTz", type="int", desc="该参数无需处理"),
     *      @Apidoc\Returned(name="iGQ", type="int", desc="设备是否已过期；1过期（限制访问）、0未过期"),
     *      @Apidoc\Returned(name="BZ", type="string", desc="设备备注信息"),
     *      @Apidoc\Returned(name="XMState", type="float", desc="休眠状态true休眠、false未休眠"),
     *      @Apidoc\Returned(name="m_iYyxsc", type="int", desc="该参数无需处理"),
     *      @Apidoc\Returned(name="m_iJlxmsc", type="int", desc="该参数无需处理"),
     *      @Apidoc\Returned(name="m_iBcxmsc", type="int", desc="该参数无需处理"),
     *      @Apidoc\Returned(name="m_iZcbs", type="int", desc="该参数无需处理"),
     *      @Apidoc\Returned(name="sSbLx", type="string", desc="设备类型:有线/无线"),
     *      @Apidoc\Returned(name="sJzZbB", type="string", desc="多基站百度坐标信息(百度坐标)格式。A,经度，纬度|B,经度，纬度|…其中字母代表基站编号、经纬度为零则无需显示"),
     *      @Apidoc\Returned(name="sJzZbG", type="string", desc="多基站GPS坐标信息(百度坐标)格式A,经度，纬度|B,经度，纬度|…其中字母代表基站编号、经纬度为零则无需显示"),
     *      @Apidoc\Returned(name="bJd", type="string", desc="百度坐标经度"),
     *      @Apidoc\Returned(name="bWd", type="string", desc="百度坐标纬度"),
     *      @Apidoc\Returned(name="SY", type="string", desc="该参数无需处理"),
     *      @Apidoc\Returned(name="CT", type="string", desc="该参数无需处理"),
     *      @Apidoc\Returned(name="ID", type="string", desc="设备ID"),
     *      @Apidoc\Returned(name="CP", type="string", desc="车牌号码"),
     *      @Apidoc\Returned(name="SIM", type="string", desc="车载手机号（GPS终端安装的SIM卡号码）"),
     *      @Apidoc\Returned(name="JD", type="string", desc="GPS坐标经度"),
     * })
     */
    public function FunDwGetOneListAPI(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunDwGetOneListAPI($request->post()));
    }

    /**
     * @Apidoc\Title("获取地址")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunDwGetDiZhi")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_CheId", type="string", require=true, desc="设备ID(车ID)")
     * @Apidoc\Param(name="p_Jd", type="double", require=true, desc="GPS经度")
     * @Apidoc\Param(name="p_Wd", type="double", require=true, desc="GPS纬度")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true, desc="数据结果集",children={
     *      @Apidoc\Returned(name="ID", type="string", desc="设备ID"),
     *      @Apidoc\Returned(name="DZ", type="string", desc="地址"),
     * })
     */
    public function FunDwGetDiZhi(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunDwGetDiZhi($request->post()));
    }

    /**
     * @Apidoc\Title("取消选择车辆")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunDwNotSel")
     * @Apidoc\Param(name="car_id", type="string", require=true)
     * @Apidoc\Returned(name="ok", type="bool")
     */
    public function FunDwNotSel(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunDwNotSel($request->post()));
    }

    /**
     * @Apidoc\Title("主页面刷新，清空选择车辆")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunClear")
     * @Apidoc\Returned(name="ok", type="bool")
     */
    public function FunClear(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunClear($request->post()));
    }

    /**
     * @Apidoc\Title("获取历史回放数据（轨迹回放）")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunHuiFang")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_CheId", type="string", require=true, desc="设备ID(车ID)")
     * @Apidoc\Param(name="p_Begin", type="string", require=true, desc="开始时间")
     * @Apidoc\Param(name="p_End", type="string", require=true, desc="结束时间")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true, desc="数据结果集",children={
     *      @Apidoc\Returned(name="m_CheId", type="string", desc="设备ID"),
     *      @Apidoc\Returned(name="m_bCom", type="bool", desc="是否压缩"),
     *      @Apidoc\Returned(name="m_iNums", type="int", desc="数量"),
     *      @Apidoc\Returned(name="m_Data", type="array", desc="数据列表",children={
     *              @Apidoc\Returned(children={
     *                   @Apidoc\Returned(name="tJd", type="int", desc="经度"),
     *                   @Apidoc\Returned(name="tWd", type="int", desc="纬度"),
     *                   @Apidoc\Returned(name="bJd", type="string", desc="百度坐标经度"),
     *                   @Apidoc\Returned(name="bWd", type="string", desc="百度坐标纬度"),
     *                   @Apidoc\Returned(name="XTSJ", type="string", desc="xt时间"),
     *                   @Apidoc\Returned(name="Gps", type="string", desc="gps时间"),
     *                   @Apidoc\Returned(name="Jd", type="string", desc="gps经度"),
     *                   @Apidoc\Returned(name="Wd", type="string", desc="gps纬度"),
     *                   @Apidoc\Returned(name="State", type="int", desc="状态"),
     *                   @Apidoc\Returned(name="Sd", type="int", desc="速度"),
     *                   @Apidoc\Returned(name="TZSC", type="string", desc="该参数无需处理"),
     *                   @Apidoc\Returned(name="Bj", type="int", desc="该参数无需处理"),
     *                   @Apidoc\Returned(name="XH", type="int", desc="该参数无需处理"),
     *                   @Apidoc\Returned(name="BL", type="int", desc="该参数无需处理"),
     *                   @Apidoc\Returned(name="Dz", type="string", desc="地址"),
     *                   @Apidoc\Returned(name="Fx", type="int", desc="该参数无需处理"),
     *                   @Apidoc\Returned(name="TZ", type="string", desc="该参数无需处理"),
     *                   @Apidoc\Returned(name="iTz", type="int", desc="该参数无需处理"),
     *              })  
     *      }) 
     * })
     */
    public function FunHuiFang(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunHuiFang($request->post()));
    }

    /**
     * @Apidoc\Title("回查最后历史数据（指定截止前的最后100条）")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunZuiHou")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_CheId", type="string", require=true, desc="设备ID(车ID)")
     * @Apidoc\Param(name="p_ShiJian", type="string", require=false, default="", desc="截止时间为空为最后(离线前)起")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true, desc="数据结果集",children={
     *      @Apidoc\Returned(name="m_CheId", type="string", desc="设备ID"),
     *      @Apidoc\Returned(name="m_bCom", type="bool", desc="是否压缩"),
     *      @Apidoc\Returned(name="m_iNums", type="int", desc="数量"),
     *      @Apidoc\Returned(name="m_Data", type="array", desc="数据列表(含经纬度、时间、速度等)") 
     * })
     */
    public function FunZuiHou(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunZuiHou($request->post()));
    }

    /**
     * @Apidoc\Title("运行状态统计")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunZhuangTaiTongJi")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_CheId", type="string", require=true, desc="车ID")
     * @Apidoc\Param(name="p_Begin", type="string", require=true, desc="开始时间")
     * @Apidoc\Param(name="p_End", type="string", require=true, desc="截止时间")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true, desc="CZhuangTai：iNum；Data 列表（Dz/Zt/Yj/Sj）",children={
     * })
     */
    public function FunZhuangTaiTongJi(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunZhuangTaiTongJi($request->post()));
    }

    /**
     * @Apidoc\Title("里程统计")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunLiChengLists")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_chePaiHao", type="string", require=true, desc="车牌号码")
     * @Apidoc\Param(name="p_startDT", type="string", require=true, desc="起始时间")
     * @Apidoc\Param(name="p_endDT", type="string", require=true, desc="截止时间")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true, desc="Result 结果码；List 列表(里程、时长、汇总标志等)")
     */
    public function FunLiChengLists(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunLiChengLists($request->post()));
    }

    /**
     * @Apidoc\Title("添加地理围栏")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunAddDiLiWeiLanApi")
     * @Apidoc\Param(name="fence", type="object", require=true, desc="围栏定义：类型、坐标、规则等")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true)
     */
    public function FunAddDiLiWeiLanApi(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunAddDiLiWeiLanApi($request->post()));
    }

    /**
     * @Apidoc\Title("删除围栏")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunDeleteWeiLanApi")
     * @Apidoc\Param(name="fence_id", type="string", require=true)
     * @Apidoc\Returned(name="ok", type="bool")
     */
    public function FunDeleteWeiLanApi(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunDeleteWeiLanApi($request->post()));
    }

    /**
     * @Apidoc\Title("获取所有围栏信息")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunGetWLInfoApi")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true)
     */
    public function FunGetWLInfoApi(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunGetWLInfoApi($request->post()));
    }

    /**
     * @Apidoc\Title("获取单个围栏信息")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunGetOneWeiLanApi")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_WlId", type="int", require=true, desc="区域id")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true, desc="WeiLan：Status/Id/Name/Type/YuanXin/BanJin/Points")
     */
    public function FunGetOneWeiLanApi(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunGetOneWeiLanApi($request->post()));
    }

    /**
     * @Apidoc\Title("给 GPS 终端设置围栏")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunAddWeiLanSheBeiApi")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_CheId", type="string", require=true, desc="设备ID")
     * @Apidoc\Param(name="p_QuYuId", type="int", require=true, desc="区域ID")
     * @Apidoc\Param(name="p_QuYuMingchen", type="string", require=false, desc="区域名称")
     * @Apidoc\Param(name="p_Yxq", type="int", require=false, desc="有效期(天)")
     * @Apidoc\Param(name="p_Type", type="int", require=true, desc="关联类型：1进；2出；3进出")
     * @Apidoc\Returned(name="ok", type="bool")
     */
    public function FunAddWeiLanSheBeiApi(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunAddWeiLanSheBeiApi($request->post()));
    }

    /**
     * @Apidoc\Title("编辑已设置围栏的设备记录")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunEditWeiLanSheBeiApi")
     * @Apidoc\Param(name="p_Wy", type="string", require=true)
     * @Apidoc\Param(name="p_Yxq", type="int", require=true, desc="有效期(天)")
     * @Apidoc\Param(name="p_Type", type="int", require=true, desc="1进；2出；3进出")
     * @Apidoc\Param(name="p_ID", type="int", require=true, desc="关联信息ID")
     * @Apidoc\Returned(name="ok", type="bool")
     */
    public function FunEditWeiLanSheBeiApi(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunEditWeiLanSheBeiApi($request->post()));
    }

    /**
     * @Apidoc\Title("取消 GPS 终端已设置的某个围栏")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunDeleteSheBeiWeiLanApi")
     * @Apidoc\Param(name="p_Wy", type="string", require=true)
     * @Apidoc\Param(name="p_ID", type="int", require=true, desc="关联信息ID")
     * @Apidoc\Returned(name="ok", type="bool")
     */
    public function FunDeleteSheBeiWeiLanApi(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunDeleteSheBeiWeiLanApi($request->post()));
    }

    /**
     * @Apidoc\Title("获取当前用户账号下所有设备信息")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunGetSbInfosApi")
     * @Apidoc\Param(name="p_Wy", type="string", require=true)
     * @Apidoc\Param(name="p_Where", type="string", require=false, desc="查询条件 设备/组名，空为全部")
     * @Apidoc\Param(name="p_QuYuId", type="int", require=false, desc="区域ID")
     * @Apidoc\Param(name="p_XuHao", type="int", require=true, desc="当前页，从0开始")
     * @Apidoc\Param(name="p_Total", type="int", require=true, desc="每页条数 默认200")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true, desc="SbInfoResult：Status；TotalCount；SbInfoList")
     */
    public function FunGetSbInfosApi(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunGetSbInfosApi($request->post()));
    }

    /**
     * @Apidoc\Title("获取设备-围栏关联关系")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunGetGlInfosApi")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true)
     */
    public function FunGetGlInfosApi(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunGetGlInfosApi($request->post()));
    }

    /**
     * @Apidoc\Title("锁车（关闭油路）")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunGetLock")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_CheId", type="string", require=true, desc="车ID")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="int", main=true, desc="返回码：0成功；1不支持；2唯一号不存在；3没有此车辆；-1异常；4指令不兼容；5时长错误；6参数有误；7无权操作")
     */
    public function FunGetLock(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunGetLock($request->post()));
    }

    /**
     * @Apidoc\Title("解锁（恢复油路）")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunReLock")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_CheId", type="string", require=true, desc="车ID")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="int", main=true, desc="返回码：0成功；1不支持；2唯一号不存在；3没有此车辆；-1异常；4指令不兼容；5时长错误；6参数有误；7无权操作")
     */
    public function FunReLock(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunReLock($request->post()));
    }

    /**
     * @Apidoc\Title("报警信息统计（概括数据，折叠状态）")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunSelectBaoJingChuLi")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="sheBeiMingCheng", type="string", require=false, desc="完整设备名称")
     * @Apidoc\Param(name="baoJingLeiXing", type="int", require=true, desc="报警类型 -1所有；1断电；2围栏；3振动；4离线；5拆除；6离开；7上线提醒；8超速；9低压；10紧急；11拖车；12干扰；13屏蔽；14备电低压；15启动；16危险区域；19组网信息；20国界；21流量超标")
     * @Apidoc\Param(name="beginDT", type="string", require=true, desc="起始时间 yyyy-MM-dd HH:mm:ss")
     * @Apidoc\Param(name="endDT", type="string", require=true, desc="截止时间 yyyy-MM-dd HH:mm:ss")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true, desc="Result；Data 列表（含 BJCS, BJLX, BJXX, DT, EarlyDT, LastDT, WXQYID/Name 等）")
     */
    public function FunSelectBaoJingChuLi(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunSelectBaoJingChuLi($request->post()));
    }

    /**
     * @Apidoc\Title("报警信息明细统计（展开状态）")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunSelectBaoJingJiLu")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="cheID", type="string", require=true, desc="设备ID/车ID")
     * @Apidoc\Param(name="baoJingDT", type="string", require=true, desc="报警日期 yyyy-MM-dd")
     * @Apidoc\Param(name="baoJingLeiXing", type="int", require=true, desc="报警类型 同上")
     * @Apidoc\Param(name="weiXianQuYuID", type="int", require=false, desc="围栏/危险区域ID")
     * @Apidoc\Param(name="earlyDT", type="string", require=false)
     * @Apidoc\Param(name="lastDT", type="string", require=false)
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true, desc="Result；Data（含 BJJL 时间列表 BJXX/BJDT/DZ 等）")
     */
    public function FunSelectBaoJingJiLu(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunSelectBaoJingJiLu($request->post()));
    }

    /**
     * @Apidoc\Title("获取车辆 OBD 数据")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunGetOBDInfos")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_CheID", type="string", require=true, desc="车ID")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true, desc="OBD：见厂家文档第36条")
     */
    public function FunGetOBDInfos(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunGetOBDInfos($request->post()));
    }

    /**
     * @Apidoc\Title("下发指定上传时间指令（H262系列）")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunZdscsj")
     * @Apidoc\Param(name="device_id", type="string", require=true)
     * @Apidoc\Param(name="upload_interval", type="int", require=true, desc="上传间隔(秒)")
     * @Apidoc\Returned(name="ok", type="bool")
     */
    public function FunZdscsj(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunZdscsj($request->post()));
    }

    /**
     * @Apidoc\Title("扩展：新增休眠天数（H262系列）")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunZdscsjEx")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_CheId", type="string", require=true, desc="车ID")
     * @Apidoc\Param(name="p_ShiJian", type="string", require=true, desc="指定上传时间 12:30/03:00")
     * @Apidoc\Param(name="p_CiShu", type="int", require=true)
     * @Apidoc\Param(name="p_ShiCang", type="int", require=true)
     * @Apidoc\Param(name="p_Gps", type="int", require=true)
     * @Apidoc\Param(name="p_Xmts", type="int", require=true, desc="休眠天数 1~15")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="int", main=true, desc="返回码同上")
     */
    public function FunZdscsjEx(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunZdscsjEx($request->post()));
    }

    /**
     * @Apidoc\Title("查询指定时间上传状态（H262系列）")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunZlChaXun")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_CheId", type="string", require=true, desc="车ID")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true, desc="CZlCx：Sj；Cs；Sc；Gps；Xmts；Dd；Sxsj")
     */
    public function FunZlChaXun(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunZlChaXun($request->post()));
    }

    /**
     * @Apidoc\Title("离线统计")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunLxtj")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_ShiChang", type="int", require=true, desc="离线时长(小时)")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="array", main=true, desc="CTjZu 列表：ZuId/Name/ZUMC/LXSL")
     */
    public function FunLxtj(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunLxtj($request->post()));
    }

    /**
     * @Apidoc\Title("离线统计获取车辆")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunLxGetChe")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_ShiChang", type="int", require=true, desc="离线时长(小时)")
     * @Apidoc\Param(name="p_ZuId", type="string", require=true, desc="组ID")
     * @Apidoc\Param(name="p_Index", type="int", require=false, default="0")
     * @Apidoc\Param(name="p_Sort", type="int", require=false, default="1")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true, desc="CTjZt：Index；ZuId；lsData 列表")
     */
    public function FunLxGetChe(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunLxGetChe($request->post()));
    }

    /**
     * @Apidoc\Title("状态统计")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunZttj")
     * @Apidoc\Param(name="car_ids", type="array", require=false)
     * @Apidoc\Param(name="start_time", type="string", require=false)
     * @Apidoc\Param(name="end_time", type="string", require=false)
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true)
     */
    public function FunZttj(Request $request): Response
    {
        $post = $request->post();
        // normalize car_ids to array
        $carIds = $post['car_ids'] ?? $post['car_id'] ?? [];
        if (is_string($carIds) && $carIds !== '') {
            $carIds = array_map('trim', explode(',', $carIds));
        } elseif (!is_array($carIds)) {
            $carIds = [];
        }
        $post['car_ids'] = $carIds;
        // normalize time formats to Y-m-d H:i:s when possible
        foreach (['start_time', 'end_time'] as $k) {
            if (isset($post[$k]) && $post[$k] !== '') {
                $v = $post[$k];
                if (!preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $v)) {
                    $ts = strtotime($v);
                    if ($ts !== false) {
                        $post[$k] = date('Y-m-d H:i:s', $ts);
                    }
                }
            }
        }
        error_log('FunZttj called: ' . json_encode($post));
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunZttj($post));
    }

    /**
     * @Apidoc\Title("状态统计获取车辆")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/FunTjGetChe")
     * @Apidoc\Param(name="p_Wy", type="string", require=true, desc="唯一号")
     * @Apidoc\Param(name="p_ZuId", type="string", require=true, desc="组ID")
     * @Apidoc\Param(name="p_Index", type="int", require=false, default="0", desc="开始编号")
     * @Apidoc\Param(name="p_Sort", type="int", require=false, default="1", desc="排序 1车牌 2离线优先")
     * @Apidoc\Returned(name="ok", type="bool")
     * @Apidoc\Returned(name="data", type="object", main=true, desc="CTjZt：Index；ZuId；lsData 列表")
     */
    public function FunTjGetChe(Request $request): Response
    {
        return $this->respond(__FUNCTION__, fn() => $this->svc->FunTjGetChe($request->post()));
    }
}
